import * as CANNON from 'cannon-es';


const boxBodies = [];
const sphereBodies = [];
let planeBody;
let physicsWorld;

setupPhysics();

self.onmessage = (e) => {
    let { action } = e.data;
    if (action == "init") {
        let { box, sphere } = e.data;
        addBoxBody(box.t, box.size);
        addSphereBody(sphere.t, sphere.r);
    }
}

function addBoxBody(t, size) {
    const boxShape = new CANNON.Box(new CANNON.Vec3(size.width / 2, size.height / 2, size.depth / 2));
    for (let i = 0; i < t; i++) {
        const chassisBody = new CANNON.Body({ mass: 1 })
        chassisBody.addShape(boxShape);
        chassisBody.position.set(getRandom(-100, 100), getRandom(3, 20), getRandom(-100, 100));
        physicsWorld.addBody(chassisBody);
        boxBodies.push(chassisBody);
    }
}

function addSphereBody(t, r) {
    const sphereShape = new CANNON.Sphere(r);
    for (let i = 0; i < t; i++) {
        const chassisBody = new CANNON.Body({ mass: 1 })
        chassisBody.addShape(sphereShape);
        chassisBody.position.set(getRandom(-100, 100), getRandom(3, 20), getRandom(-100, 100));
        physicsWorld.addBody(chassisBody);
        sphereBodies.push(chassisBody);
    }

}

function getRandom(a, b, isInt = false) {
    if (isInt) {
        return Math.floor(Math.random() * (b - a + 1)) + a;
    } else {
        return Math.random() * (b - a) + a;
    }
}

function setupPhysics() {
    physicsWorld = new CANNON.World({
        gravity: new CANNON.Vec3(0, -9.82, 0),
    });
    physicsWorld.broadphase = new CANNON.SAPBroadphase(physicsWorld);
    physicsWorld.defaultContactMaterial.friction = 0.2;
    // cannonDebugger = new CannonDebugger(scene, physicsWorld);

    const planeShape = new CANNON.Plane()
    planeBody = new CANNON.Body({ mass: 0 })
    planeBody.addShape(planeShape);

    planeBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI * 0.5);
    planeBody.position.set(0, -4, 0);

    physicsWorld.addBody(planeBody);
}

update();

function update() {
    physicsWorld.step(1 / 60);
    let planeData = getTransformData(planeBody);
    let sphereData = sphereBodies.map(i=>getTransformData(i));
    let boxData = boxBodies.map(i=>getTransformData(i));
    self.postMessage({ action: "update", planeData, sphereData, boxData })
    requestAnimationFrame(update);
}

function getTransformData(body) {
    let p = { x: body.position.x, y: body.position.y, z: body.position.z };
    let { x, y, z, w } = body.quaternion;
    let q = { x, y, z, w };
    return {
        p, q
    }
}